package com.fzz.learnitservice.utils;

import com.fzz.learnitservice.pojo.properties.JwtProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.SignatureException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
public class JwtUtils {

    private final JwtProperties jwtProperties;
    private final RedisTemplate<String, String> redisTemplate;
    private static final String accessTokenKey = "login:token:";

    /**
     * 生成 JWT Token
     */
    public String generateToken(Long userId, String username) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userId);
        claims.put("username", username);

        String accessToken =  Jwts.builder()
                .setClaims(claims) // 设置自定义负载
                .setSubject(String.valueOf(userId)) // 一般也保留用户ID作为主体
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + jwtProperties.getExpire()))
                .signWith(SignatureAlgorithm.HS256, jwtProperties.getSecret())
                .compact();

        // Redis设置过期时间，直接用JWT过期时间计算
        String redisKey = accessTokenKey + userId;
        redisTemplate.opsForValue().set(redisKey, accessToken, jwtProperties.getExpire(), TimeUnit.MILLISECONDS);

        return accessToken;
    }

    /**
     * 解析 Token 获取 Claims
     */
    private Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(jwtProperties.getSecret())
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 根据 Token 获取用户ID
     */
    public Long getUserId(String token) {
        return Long.parseLong(parseToken(token).get("userId").toString());
    }

    /**
     * 根据 Token 获取用户名
     */
    public String getUsername(String token) {
        return parseToken(token).get("username").toString();
    }

    /**
     * 校验 Token 是否有效
     */
    public boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            Date expiration = claims.getExpiration();
            return expiration.after(new Date());
        } catch (ExpiredJwtException e) {
            System.out.println("❌ Token 已过期");
        } catch (SignatureException e) {
            System.out.println("❌ Token 签名无效");
        } catch (Exception e) {
            System.out.println("❌ Token 解析失败: " + e.getMessage());
        }
        return false;
    }

}

